/*
 * Copyright (C) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup AVMuxer
 * @{
 *
 * @brief AVMuxer模块提供用于音视频封装功能的函数。
 * 
 * @syscap SystemCapability.Multimedia.Media.Muxer
 * @since 10
 */


/**
 * @file native_avmuxer.h
 *
 * @brief 声明用于音视频封装的Native API。
 *
 * @library libnative_media_avmuxer.so
 * @since 10
 */
 
#ifndef NATIVE_AVMUXER_H
#define NATIVE_AVMUXER_H

#include <stdint.h>
#include <stdio.h>
#include "native_avcodec_base.h"
#include "native_averrors.h"
#include "native_avformat.h"
#include "native_avmemory.h"
#include "native_avbuffer.h"

#ifdef __cplusplus
extern "C" {
#endif
/**
 * @brief 为封装接口定义native层对象。
 * @since 10
 */
typedef struct OH_AVMuxer OH_AVMuxer;

/**
 * @brief 通过文件描述符fd和封装格式创建OH_AVMuxer实例。
 * @syscap SystemCapability.Multimedia.Media.Muxer
 * @param fd 用读写方式打开（O_RDWR），由调用者关闭该fd。
 * @param format 封装输出的文件格式，参考{@link OH_AVOutputFormat}。
 * @return 返回一个指向OH_AVMuxer实例的指针, 需要调用OH_AVMuxer_Destroy销毁。
 * @since 10
 */
OH_AVMuxer *OH_AVMuxer_Create(int32_t fd, OH_AVOutputFormat format);

/**
 * @brief 设置视频的旋转角度（顺时针）。
 * Note: 这个接口必须在OH_AVMuxer_Start前调用。
 * @syscap SystemCapability.Multimedia.Media.Muxer
 * @param muxer 指向OH_AVMuxer实例的指针。
 * @param rotation 角度，必须为0、90、180 或 270。
 * @return 执行成功返回AV_ERR_OK，否则返回具体错误码，参考{@link OH_AVErrCode}。
 * {@link AV_ERR_INVALID_VAL}，muxer为空指针，或rotation无效。
 * {@link AV_ERR_OPERATE_NOT_PERMIT}，不允许调用接口，它在无效状态下被调用。
 * @since 10
 */
OH_AVErrCode OH_AVMuxer_SetRotation(OH_AVMuxer *muxer, int32_t rotation);

/**
 * @brief 向封装器添加媒体轨。
 * Note: 该接口必须在OH_AVMuxer_Start前调用。
 * @syscap SystemCapability.Multimedia.Media.Muxer
 * @param muxer 指向OH_AVMuxer实例的指针。
 * @param trackIndex 用于获取该轨的索引，该值在OH_AVMuxer_WriteSample接口中使用。
 * 如果媒体轨添加成功，该值大于或等于0，否则小于0。
 * @param trackFormat 指向OH_AVFormat实例的指针。
 * @return 执行成功返回AV_ERR_OK，否则返回具体错误码，参考{@link OH_AVErrCode}。
 * {@link AV_ERR_INVALID_VAL}，muxer为空指针，或trackIndex无效，或trackFormat无效。
 * {@link AV_ERR_OPERATE_NOT_PERMIT}，不允许调用接口，它在无效状态下被调用。
 * {@link AV_ERR_UNSUPPORT}，不支持的mime类型。
 * {@link AV_ERR_NO_MEMORY}，申请内存失败。
 * {@link AV_ERR_UNKNOWN}，未知错误。
 * @since 10
 */
OH_AVErrCode OH_AVMuxer_AddTrack(OH_AVMuxer *muxer, int32_t *trackIndex, OH_AVFormat *trackFormat);

/**
 * @brief 开始封装。
 * Note: 该接口必须在OH_AVMuxer_AddTrack后，OH_AVMuxer_WriteSample前调用。
 * @syscap SystemCapability.Multimedia.Media.Muxer
 * @param muxer 指向OH_AVMuxer实例的指针。
 * @return 执行成功返回AV_ERR_OK，否则返回具体错误码，参考{@link OH_AVErrCode}。
 * {@link AV_ERR_INVALID_VAL}，muxer为空指针。
 * {@link AV_ERR_OPERATE_NOT_PERMIT}，不允许调用接口，它在无效状态下被调用。
 * {@link AV_ERR_UNKNOWN}，未知错误。
 * @since 10
 */
OH_AVErrCode OH_AVMuxer_Start(OH_AVMuxer *muxer);

/**
 * @brief 将数据写入封装器。 
 * Note: 该接口必须在OH_AVMuxer_Start后，OH_AVMuxer_Stop前调用。
 * 调用者需要保证数据写入正确的轨道，并按时间顺序排列。
 * @syscap SystemCapability.Multimedia.Media.Muxer
 * @param muxer 指向OH_AVMuxer实例的指针。
 * @param trackIndex 数据对应的媒体轨的索引。
 * @param sample 写入的数据，编码或解封装得到的数据。
 * @param info 写入数据的信息，参考{@link OH_AVCodecBufferAttr}。
 * @return 执行成功返回AV_ERR_OK，否则返回具体错误码，参考{@link OH_AVErrCode}。
 * {@link AV_ERR_INVALID_VAL}，muxer为空指针，或trackIndex无效，或sample无效，或info无效。
 * {@link AV_ERR_OPERATE_NOT_PERMIT}，不允许调用接口，它在无效状态下被调用。
 * {@link AV_ERR_NO_MEMORY}，申请内存失败。
 * {@link AV_ERR_UNKNOWN}，未知错误。
 * @deprecated since 11
 * @useinstead OH_AVMuxer_WriteSampleBuffer
 * @since 10
 */
OH_AVErrCode OH_AVMuxer_WriteSample(OH_AVMuxer *muxer, uint32_t trackIndex, OH_AVMemory *sample, OH_AVCodecBufferAttr info);

/**
 * @brief 将数据写入封装器。 
 * Note: 该接口必须在OH_AVMuxer_Start后，OH_AVMuxer_Stop前调用。
 * 调用者需要保证数据写入正确的轨道，并按时间顺序排列。
 * @syscap SystemCapability.Multimedia.Media.Muxer
 * @param muxer 指向OH_AVMuxer实例的指针。
 * @param trackIndex 数据对应的媒体轨的索引。
 * @param sample 写入的数据，编码或解封装得到的数据。包含数据与数据属性
 * @return 执行成功返回AV_ERR_OK，否则返回具体错误码，参考{@link OH_AVErrCode}。
 * {@link AV_ERR_INVALID_VAL}，muxer为空指针，或trackIndex无效，或sample无效。
 * {@link AV_ERR_OPERATE_NOT_PERMIT}，不允许调用接口，它在无效状态下被调用。
 * {@link AV_ERR_NO_MEMORY}，申请内存失败。
 * {@link AV_ERR_UNKNOWN}，未知错误。
 * @since 11
 */
OH_AVErrCode OH_AVMuxer_WriteSampleBuffer(OH_AVMuxer *muxer, uint32_t trackIndex, const OH_AVBuffer *sample);

/**
 * @brief 停止封装。
 * Note: 封装器一旦停止，不能重新开始。
 * @syscap SystemCapability.Multimedia.Media.Muxer
 * @param muxer 指向OH_AVMuxer实例的指针。
 * @return 执行成功返回AV_ERR_OK，否则返回具体错误码，参考{@link OH_AVErrCode}。
 * {@link AV_ERR_INVALID_VAL}，muxer为空指针。
 * {@link AV_ERR_OPERATE_NOT_PERMIT}，不允许调用接口，它在无效状态下被调用。
 * @since 10
 */
OH_AVErrCode OH_AVMuxer_Stop(OH_AVMuxer *muxer);

/**
 * @brief 清理内部资源，销毁OH_AVMuxer实例。
 * @syscap SystemCapability.Multimedia.Media.Muxer
 * @param muxer 指向OH_AVMuxer实例的指针。
 * @return 执行成功返回AV_ERR_OK，需调用者置空muxer；否则返回具体错误码，参考{@link OH_AVErrCode}。
 * {@link AV_ERR_INVALID_VAL}，muxer为空指针。
 * @since 10
 */
OH_AVErrCode OH_AVMuxer_Destroy(OH_AVMuxer *muxer);

#ifdef __cplusplus
}
#endif

#endif // NATIVE_AVMUXER_H

/** @} */